package cn.miju.wechatpay.handler;

import cn.miju.wechatpay.constant.WechatpayConstant;
import cn.miju.wechatpay.content.CodeMessage;
import cn.miju.wechatpay.properties.WechatpayProperties;
import cn.miju.wechatpay.request.WechatpayCreateQrcodeOrderReq;
import cn.miju.wechatpay.request.WechatpayRefundOrderReq;
import cn.miju.wechatpay.response.WechatpayCreateQrcodeOrderResp;
import cn.miju.wechatpay.response.WechatpayRefundOrderResp;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * <pre>
 * 业务类
 * </pre>
 *
 * @author Huzb
 * @version 1.0.0
 * @since 2023年05月04日 16:41
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WechatpayRefundOrderHandler extends AbstractWechatpayHandler<WechatpayRefundOrderReq, WechatpayRefundOrderResp> {


    /**
     * 请求参数前置处理
     *
     * @param req 请求参数
     * @return 结果
     */
    @Override
    protected String beforeRequest(WechatpayRefundOrderReq req) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("transaction_id", req.getTransactionId());
        jsonObject.put("out_trade_no", req.getOutTradeNo());
        jsonObject.put("out_refund_no", req.getOutRefundNo());
        jsonObject.put("reason", req.getReason());
        jsonObject.put("notify_url", req.getNotifyUrl());
        JSONObject amount = jsonObject.putObject("amount");
        amount.put("refund", req.getRefund());
        amount.put("total", req.getTotal());
        amount.put("currency", "CNY");

        return super.requsetAddOptParams(jsonObject, req.getOptionalParams());
    }

    /**
     * 核心执行
     *
     * @param req 请求参数
     * @return 结果
     */
    @Override
    public WechatpayRefundOrderResp doPlan(WechatpayRefundOrderReq req) {
        WechatpayProperties wechatpayProperties = req.getWechatpayProperties();
        CloseableHttpClient httpClient = super.getWechatpayClient(wechatpayProperties);
        String paramStr = this.beforeRequest(req);
        HttpPost httpPost = super.getHttpPost(wechatpayProperties.getUrl() + WechatpayConstant.ApiUri.REFUND,
                new StringEntity(paramStr, StandardCharsets.UTF_8));

        CloseableHttpResponse response = null;
        WechatpayRefundOrderResp resp;

        try {
            try {
                log.info("API--申请退款--【/v3/refund/domestic/refunds】-->Request：{}", paramStr);
                response = httpClient.execute(httpPost);
                String resultStr = EntityUtils.toString(response.getEntity());
                int statusCode = response.getStatusLine().getStatusCode();
                log.info("API--申请退款--【/v3/refund/domestic/refunds】-->httpCode:{} Response：{}", statusCode, resultStr);
                resp = this.afterResponse(resultStr, statusCode);
            } finally {
                if (response != null) {
                    response.close();
                }
            }
        } catch (IOException e) {
            log.error("API--申请退款--【/v3/refund/domestic/refunds】-->Exception：{}", e.getMessage(), e);
            return WechatpayRefundOrderResp.builder()
                    .code(CodeMessage.FAIL.getCode())
                    .msg(CodeMessage.FAIL.getMsg() + e.getMessage()).build();
        }

        return resp;
    }

    /**
     * 响应参数后置处理
     *
     * @param result     响应报文
     * @param statusCode 响应状态码
     * @return 结果
     */
    @Override
    protected WechatpayRefundOrderResp afterResponse(String result, int statusCode) {
        JSONObject jsonObject = JSON.parseObject(result);
        if (statusCode == SUCCESS_CODE) {
            WechatpayRefundOrderResp resp = JSON.parseObject(result, WechatpayRefundOrderResp.class);
            resp.setCode(CodeMessage.SUCCESS.getCode());
            resp.setMsg(CodeMessage.SUCCESS.getMsg());
            return resp;
        } else {
            return WechatpayRefundOrderResp.builder()
                    .code(CodeMessage.FAIL.getCode())
                    .msg(CodeMessage.FAIL.getMsg() + "【" + jsonObject.get("code") + "】" + jsonObject.get("message"))
                    .build();
        }
    }
}
